using System;
using System.Collections.Generic;
using Volo.Abp.Domain.Entities;
using Matrix.ServiceDiscovery.Enums;

namespace Matrix.ServiceDiscovery.Entities;

/// <summary>
/// 负载均衡配置实体
/// </summary>
public class LoadBalancingConfig : Entity<Guid>
{
    /// <summary>
    /// 服务ID
    /// </summary>
    public virtual Guid ServiceId { get; protected set; }

    /// <summary>
    /// 负载均衡策略
    /// </summary>
    public virtual LoadBalancingStrategy Strategy { get; protected set; }

    /// <summary>
    /// 是否启用健康检查
    /// </summary>
    public virtual bool EnableHealthCheck { get; protected set; }

    /// <summary>
    /// 健康检查间隔
    /// </summary>
    public virtual TimeSpan HealthCheckInterval { get; protected set; }

    /// <summary>
    /// 失败阈值
    /// </summary>
    public virtual int FailureThreshold { get; protected set; }

    /// <summary>
    /// 成功阈值
    /// </summary>
    public virtual int SuccessThreshold { get; protected set; }

    /// <summary>
    /// 超时时间
    /// </summary>
    public virtual TimeSpan Timeout { get; protected set; }

    /// <summary>
    /// 策略参数
    /// </summary>
    public virtual Dictionary<string, object> Parameters { get; protected set; } = new();

    protected LoadBalancingConfig() { }

    public LoadBalancingConfig(
        Guid id,
        Guid serviceId,
        LoadBalancingStrategy strategy = LoadBalancingStrategy.RoundRobin) : base(id)
    {
        ServiceId = serviceId;
        Strategy = strategy;
        EnableHealthCheck = true;
        HealthCheckInterval = TimeSpan.FromSeconds(30);
        FailureThreshold = 3;
        SuccessThreshold = 2;
        Timeout = TimeSpan.FromSeconds(5);
    }

    public void UpdateStrategy(LoadBalancingStrategy strategy)
    {
        Strategy = strategy;
    }

    public void UpdateHealthCheckSettings(
        bool enable,
        TimeSpan? interval = null,
        int? failureThreshold = null,
        int? successThreshold = null,
        TimeSpan? timeout = null)
    {
        EnableHealthCheck = enable;
        if (interval.HasValue) HealthCheckInterval = interval.Value;
        if (failureThreshold.HasValue) FailureThreshold = failureThreshold.Value;
        if (successThreshold.HasValue) SuccessThreshold = successThreshold.Value;
        if (timeout.HasValue) Timeout = timeout.Value;
    }

    public void SetParameter(string key, object value)
    {
        Parameters[key] = value;
    }

    public void RemoveParameter(string key)
    {
        Parameters.Remove(key);
    }

    public T? GetParameter<T>(string key, T? defaultValue = default)
    {
        if (Parameters.TryGetValue(key, out var value) && value is T typedValue)
        {
            return typedValue;
        }
        return defaultValue;
    }
}